/*
 * Filename:    WorkFlowServiceImpl.java
 * Copyright:   2014 中国平安保险（集团）股份有限公司 版权所有
 * Company:     平安科技养老险及健康险系统开发部
 * Create at:   2014年10月29日
 */
package com.paic.mhis.hcpms.trust.biz.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.paic.mhis.hcpms.common.workflow.dto.HcpmsWFParamDTO;
import com.paic.mhis.hcpms.common.workflow.dto.HcpmsWFTaskDTO;
import com.paic.mhis.hcpms.common.workflow.dto.WorkFlowActinstDTO;
import com.paic.mhis.hcpms.common.workflow.dto.WorkFlowGtasksDTO;
import com.paic.mhis.hcpms.common.workflow.dto.WorkFlowTaskTypeDTO;
import com.paic.mhis.hcpms.common.workflow.dto.WorkFlowTransDTO;
import com.paic.mhis.hcpms.common.workflow.vo.HcpmsWFParamVO;
import com.paic.mhis.hcpms.common.workflow.vo.HcpmsWFProcessVO;
import com.paic.mhis.hcpms.common.workflow.vo.HcpmsWorkFlowVO;
import com.paic.mhis.hcpms.trust.biz.service.IntegrityWFService;
import com.paic.mhis.hcpms.trust.intergration.dao.IntegrityWFDAO;
import com.paic.mhis.hcpms.trust.util.TrustConstants;

@Service("integrityWFService")
public class IntegrityWFServiceImpl implements IntegrityWFService {
	@Autowired
	private IntegrityWFDAO integrityWFDAO;

	@Override
	public HcpmsWFTaskDTO getWorkFlowTask(HcpmsWFTaskDTO dto) {
		return integrityWFDAO.getWorkFlowTask(dto);
	}

	/**
	 * 启动流程
	 */
	@Override
	public HcpmsWFTaskDTO startProcess(HcpmsWorkFlowVO vo) throws Exception {
		// 整理流程数据,并初始化任务流程
		HcpmsWFTaskDTO taskDto = new HcpmsWFTaskDTO();
		taskDto.setTaskNo(vo.getTaskNo());
		taskDto.setTaskType(vo.getTaskType());
		taskDto.setFlag(TrustConstants.FLOW_ING);
		String wfNo = this.getWFNoByTaskType(taskDto.getTaskType()).getWfNo();
		taskDto.setWfNo(wfNo);
		taskDto.setActCurrent(TrustConstants.FLOW_START_0);
		taskDto.setIsValid(TrustConstants.IS_VALID_0);
		/** 判断是否已启动 **/
		HcpmsWFTaskDTO task = this.getWorkFlowTask(taskDto);
		if (task != null) {
			return task;
		}
		taskDto.setCreatedBy(vo.getActCurrent());
		taskDto.setUpdatedBy(vo.getActCurrent());
		integrityWFDAO.insertWorkFlowTask(taskDto);
		// 自动流转
		vo.setWfNo(wfNo);
		vo.setActNo(taskDto.getActCurrent());
		vo.setRole(null);
		vo.setActCurrent(null);
		return this.processFlow(vo);
	}
	/**
	 * 查询任务信息
	 * @param vo
	 * @return
	 * @throws Exception
	 */
	private HcpmsWFTaskDTO findWorkFlowTask(HcpmsWorkFlowVO vo) throws Exception{
		// 整理流程数据,并初始化任务流程
		HcpmsWFTaskDTO taskDto = new HcpmsWFTaskDTO();
		taskDto.setTaskNo(vo.getTaskNo());
		taskDto.setTaskType(vo.getTaskType());
		taskDto.setFlag(TrustConstants.FLOW_ING);
		String wfNo = this.getWFNoByTaskType(vo.getTaskType()).getWfNo();
		taskDto.setWfNo(wfNo);
		taskDto.setActCurrent(TrustConstants.FLOW_START_0);
		taskDto.setIsValid(TrustConstants.IS_VALID_0);
		/** 判断是否已启动 **/
		HcpmsWFTaskDTO task = this.getWorkFlowTask(taskDto);
		return task;
	} 
	
	/**
	 * 流转
	 * 
	 * @throws Exception
	 */
	@Override
	public HcpmsWFTaskDTO processFlow(HcpmsWorkFlowVO vo) throws Exception {
		HcpmsWFTaskDTO taskDto = new HcpmsWFTaskDTO();
		taskDto.setTaskType(vo.getTaskType());
		// 获取流程编号
		String wfNo = vo.getWfNo();
		if (wfNo == null || "".equals(wfNo)) {
			wfNo = this.getWFNoByTaskType(taskDto.getTaskType()).getWfNo();
		}
		if (!"".equals(vo.getNextActNo()) && vo.getNextActNo() != null) {
			taskDto.setActCurrent(vo.getNextActNo());
			taskDto.setAssigner(vo.getAssigner());
			taskDto.setAuthorizerType(TrustConstants.PERSON_TYPE);
		} else {
			// 查询可执行的跳转节点
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("taskNo", vo.getTaskNo());
			param.put("wfNo", wfNo);
			param.put("actCurrent", vo.getActNo());
			param.put("role", vo.getRole());
			Map<String, String> condition = vo.getParamValue();
			if (condition != null && condition.size() > 0) {
				Iterator iter = condition.entrySet().iterator();
				Map.Entry entry = (Map.Entry) iter.next();
				param.put("paramCode", entry.getKey());
				param.put("paramValue", entry.getValue());
			}
			WorkFlowTransDTO actNext = this.getActNext(param);
			taskDto.setActCurrent(actNext.getActNext());
			// 处理当前处理人
			String assigner = vo.getAssigner();
			if (!"".equals(assigner) && assigner != null) {
				taskDto.setAssigner(assigner);
				taskDto.setAuthorizerType(TrustConstants.PERSON_TYPE);
			} else {
				taskDto.setAssigner(actNext.getAuthorizer());
				taskDto.setAuthorizerType(TrustConstants.GROUP_TYPE);
			}
		}
		taskDto.setUpdatedBy(vo.getActCurrent());
		taskDto.setTaskNo(vo.getTaskNo());
		
		integrityWFDAO.updateWorkFlowTask(taskDto);
		return taskDto;
	}

	/**
	 * 更新当前处理人
	 * 
	 * @throws Exception
	 */
	@Override
	public HcpmsWFTaskDTO updateWorkFlowAssigner(String taskNo, String assigner) throws Exception {
		HcpmsWFTaskDTO taskDto = new HcpmsWFTaskDTO();
		taskDto.setTaskNo(taskNo);
		taskDto.setAssigner(assigner);
		taskDto.setAuthorizerType("01");
		integrityWFDAO.updateWorkFlowTask(taskDto);
		return taskDto;
	}

	/**
	 * 流程的创建,跳转，结束
	 */
	@Override
	public void processWorkFlow(HcpmsWorkFlowVO vo) {
		if (!isNull(vo.getTaskid()) && !isNull(vo.getNextActNo()) && !isNull(vo.getAssigner())) {
			HcpmsWFTaskDTO taskDto = new HcpmsWFTaskDTO();
			taskDto.setIdWfTask(vo.getTaskid());
			taskDto.setActCurrent(vo.getNextActNo());
			taskDto.setAssigner(vo.getAssigner());
			taskDto.setUpdatedBy(vo.getActCurrent());
			integrityWFDAO.updateWorkFlowTask(taskDto);
		} else if (!isNull(vo.getNextActNo()) && !isNull(vo.getAssigner())) {
			HcpmsWFTaskDTO dto = new HcpmsWFTaskDTO();
			dto.setWfNo(vo.getWfNo());
			dto.setTaskNo(vo.getTaskNo());
			dto.setTaskType(vo.getTaskType());
			HcpmsWFTaskDTO taskDto = integrityWFDAO.getWorkFlowTask(dto);
			if (taskDto == null) {
				dto.setActCurrent(vo.getNextActNo());
				dto.setAssigner(vo.getAssigner());
				dto.setCreatedBy(vo.getActCurrent());
				dto.setUpdatedBy(vo.getActCurrent());
				dto.setFlag(TrustConstants.FLOW_ING);
				dto.setIsValid("0");
				integrityWFDAO.insertWorkFlowTask(dto);
			} else {
				taskDto.setActCurrent(vo.getNextActNo());
				taskDto.setAssigner(vo.getAssigner());
				taskDto.setUpdatedBy(vo.getActCurrent());
				if (TrustConstants.FLOW_END_1.equals(vo.getNextActNo())) {
					dto.setFlag(TrustConstants.FLOW_END);
				}
				integrityWFDAO.updateWorkFlowTask(taskDto);
			}
		} else {
			HcpmsWFTaskDTO dto = new HcpmsWFTaskDTO();
			dto.setWfNo(vo.getWfNo());
			dto.setTaskNo(vo.getTaskNo());
			dto.setTaskType(vo.getTaskType());
			HcpmsWFTaskDTO taskDto = integrityWFDAO.getWorkFlowTask(dto);
			if (taskDto == null) {
				WorkFlowTransDTO transDto = new WorkFlowTransDTO();
				transDto.setActCurrent(TrustConstants.FLOW_START_0);
				transDto.setWfNo(vo.getWfNo());
				List<WorkFlowTransDTO> tranList = integrityWFDAO.getTransList(transDto);
				if (tranList.size() > 1) {
					List<String> list = new ArrayList<String>();
					list.add("type");
					Map<String, String> map = new HashMap<String, String>();
					map.put("type", vo.getTaskType());
					transDto = getParamTrans(tranList, list, map);
				} else {
					transDto = tranList.get(0);
				}
				if (transDto == null) {
					System.out.println("");
					return;
				}
				taskDto = dto;
				taskDto.setActCurrent(transDto.getActNext());
				taskDto.setAssigner(vo.getActCurrent());
				taskDto.setCreatedBy(vo.getActCurrent());
				taskDto.setUpdatedBy(vo.getActCurrent());
				taskDto.setFlag(TrustConstants.FLOW_ING);
				taskDto.setIsValid("0");
				integrityWFDAO.insertWorkFlowTask(taskDto);
				taskDto = integrityWFDAO.getWorkFlowTask(dto);
			}
			WorkFlowTransDTO transDto = new WorkFlowTransDTO();
			transDto.setActCurrent(taskDto.getActCurrent());
			transDto.setWfNo(vo.getWfNo());
			List<WorkFlowTransDTO> tranList = integrityWFDAO.getTransList(transDto);
			if (tranList.size() > 1) {
				transDto = getParamTrans(tranList, vo.getParam(), vo.getParamValue());
			} else {
				transDto = tranList.get(0);
			}
			if (transDto == null) {
				System.out.println("");
				return;
			}
			taskDto.setActCurrent(transDto.getActNext());
			if (!isNull(vo.getAssigner())) {
				taskDto.setAssigner(vo.getAssigner());
			} else {
				taskDto.setAssigner(transDto.getAuthorizer());
			}
			taskDto.setUpdatedBy(vo.getActCurrent());
			if (TrustConstants.FLOW_END_1.equals(vo.getNextActNo())) {
				dto.setFlag(TrustConstants.FLOW_END);
			}
			integrityWFDAO.updateWorkFlowTask(taskDto);
		}
	}

	/**
	 * 流程终止
	 * 
	 * @param vo
	 */
	@Override
	public void topWorkFlow(HcpmsWorkFlowVO vo) {
		HcpmsWFTaskDTO dto = new HcpmsWFTaskDTO();
		dto.setWfNo(vo.getWfNo());
		dto.setTaskNo(vo.getTaskNo());
		dto.setTaskType(vo.getTaskType());
		HcpmsWFTaskDTO taskDto = integrityWFDAO.getWorkFlowTask(dto);
		dto.setIdWfTask(taskDto.getIdWfTask());
		dto.setFlag(TrustConstants.FLOW_STOP);
		dto.setAssigner(vo.getActCurrent());
		integrityWFDAO.updateWorkFlowTask(dto);
	}

	@Override
	public HcpmsWFProcessVO getWFProcsee(HcpmsWorkFlowVO vo) {
		HcpmsWFTaskDTO dto = new HcpmsWFTaskDTO();
		dto.setWfNo(vo.getWfNo());
		dto.setTaskNo(vo.getTaskNo());
		dto.setTaskType(vo.getTaskType());
		dto = integrityWFDAO.getWorkFlowTask(dto);
		HcpmsWFProcessVO process = new HcpmsWFProcessVO();
		process.setTaskId(dto.getIdWfTask());
		process.setActNo(dto.getActCurrent());
		process.setAssigner(dto.getAssigner());
		process.setParamList(getWFParamList(dto));
		return process;
	}

	private List<HcpmsWFParamVO> getWFParamList(HcpmsWFTaskDTO dto) {
		List<HcpmsWFParamVO> list = new ArrayList<HcpmsWFParamVO>();
		List<HcpmsWFParamDTO> paramList = integrityWFDAO.getWFParamList(dto);
		for (HcpmsWFParamDTO param : paramList) {
			HcpmsWFParamVO vo = new HcpmsWFParamVO();
			vo.setParamId(param.getParamId());
			vo.setParamCode(param.getParamCode());
			vo.setParamName(param.getParamName());
			vo.setParamValue(param.getParamValue());
			list.add(vo);
		}
		return list;
	}

	private WorkFlowTransDTO getParamTrans(List<WorkFlowTransDTO> tranList, List<String> param,
			Map<String, String> paramValue) {
		if (param.size() > 0 || paramValue.size() > 0) {
			return null;
		}
		for (WorkFlowTransDTO dto : tranList) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("actTranNo", dto.getActTranNo());
			map.put("name", param);
			map.put("value", paramValue);
			if (integrityWFDAO.getConditionList(map).size() == param.size()) {
				return dto;
			}
		}
		return null;
	}

	public boolean isNull(String str) {
		if (!"".equals(str) && str != null) {
			return false;
		}
		return true;
	}

	/**
	 * 查询流程中的节点列表
	 */
	@Override
	public List<WorkFlowActinstDTO> getActinstInfo(String taskType) {
		List<WorkFlowActinstDTO> wfActinstList = integrityWFDAO.getActinstList(taskType);

		return wfActinstList;
	}

	@Override
	public List<WorkFlowGtasksDTO> getGtasks(String assigner, String role) {
		List<WorkFlowGtasksDTO> taskList = new ArrayList<WorkFlowGtasksDTO>();
		taskList.addAll(this.getGtasksByAssigner(assigner));
		taskList.addAll(this.getGtasksByGroup(role));
		return taskList;
	}

	@Override
	public List<WorkFlowGtasksDTO> getGtasksByAssigner(String assigner) {
		List<WorkFlowGtasksDTO> taskList = integrityWFDAO.getGtasksByAssigner(assigner);
		return taskList;
	}

	@Override
	public List<WorkFlowGtasksDTO> getGtasksByGroup(String role) {
		List<WorkFlowGtasksDTO> taskList = integrityWFDAO.getGtasksByGroup(role);
		return taskList;
	}

	/**
	 * 查询任务的当前可操作跳转
	 */
	@Override
	public List<WorkFlowGtasksDTO> getOperatorTran(String assigner, List<String> roleList, List<String> taskList) {
		List<WorkFlowGtasksDTO> tranList = new ArrayList<WorkFlowGtasksDTO>();
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("assigner", assigner);
		param.put("taskList", taskList);
		for (String role : roleList) {
			param.put("role", role);
			tranList.addAll(integrityWFDAO.getOperatorTran(param));
		}
		return tranList;
	}

	/**
	 * 根据任务类型获取流程
	 */
	@Override
	public WorkFlowTaskTypeDTO getWFNoByTaskType(String taskType) throws Exception {
		List<WorkFlowTaskTypeDTO> wfList = integrityWFDAO.getWFNoByTaskType(taskType);
		if (wfList != null && wfList.size() > 0) {
			return wfList.get(0);
		} else {
			throw new RuntimeException(TrustConstants.ERROR_MSG_2);
		}
	}

	/**
	 * 查询符合条件的下一节点
	 * 
	 * @throws Exception
	 */
	private WorkFlowTransDTO getActNext(Map<String, Object> param) throws Exception {
		List<WorkFlowTransDTO> tranList = integrityWFDAO.getActNext(param);
		if (tranList != null && tranList.size() > 0) {
			return tranList.get(0);
		} else {
			throw new RuntimeException(TrustConstants.ERROR_MSG_1);
		}

	}

	/**
	 * 绑定操作人和判断操作权限 0 有操作权限 1没有操作权限 2节点已经变更
	 */
	@Override
	public String vilidateOrBindUser(HcpmsWorkFlowVO vo) {
		HcpmsWFTaskDTO taskDto = new HcpmsWFTaskDTO();
		taskDto.setTaskNo(vo.getTaskNo());
		taskDto.setTaskType(vo.getTaskType());
		taskDto.setFlag(TrustConstants.FLOW_ING);
		String processState = TrustConstants.PROCESS_IN_POWER;
		try {
			String wfNo = this.getWFNoByTaskType(vo.getTaskType()).getWfNo();
			taskDto.setWfNo(wfNo);
			taskDto = this.getWorkFlowTask(taskDto);
			if (taskDto == null) {
				return processState;
			}
			if (!taskDto.getActCurrent().equals(vo.getActNo())) {
				processState = TrustConstants.PROCESS_NOT_POWER;
			} else if (taskDto.getAuthorizerType().equals(TrustConstants.GROUP_TYPE)) {
				taskDto.setAuthorizerType(TrustConstants.PERSON_TYPE);
				taskDto.setAssigner(vo.getActCurrent());
				integrityWFDAO.updateWorkFlowTask(taskDto);
			} else if (taskDto.getAuthorizerType().equals(TrustConstants.PERSON_TYPE)
					&& !taskDto.getAssigner().equals(vo.getActCurrent())) {
				processState = TrustConstants.PROCESS_OUT_POWER;
			}
		} catch (Exception e) {
			processState = TrustConstants.PROCESS_OUT_POWER;
			e.printStackTrace();
		}
		return processState;
	}

	/**
	 * 流程终止
	 * 
	 * @param vo
	 */
	@Override
	public void deleteWorkFlow(HcpmsWorkFlowVO vo) {
		HcpmsWFTaskDTO dto = new HcpmsWFTaskDTO();
		try {
			String wfNo = this.getWFNoByTaskType(vo.getTaskType()).getWfNo();
			dto.setWfNo(wfNo);
			dto.setTaskNo(vo.getTaskNo());
			dto.setTaskType(vo.getTaskType());
			dto.setIsValid(TrustConstants.IS_VALID_1);
			dto.setFlag(TrustConstants.FLOW_STOP);
			integrityWFDAO.updateWorkFlowTask(dto);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
